
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                               clock.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                                                    Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

#include "type.h"
#include "stdio.h"
#include "const.h"
#include "protect.h"
#include "string.h"
#include "fs.h"
#include "proc.h"
#include "tty.h"
#include "console.h"
#include "global.h"
#include "proto.h"
#include "video.h"


/*======================================================================*
                           clock_handler
 *======================================================================*/
PUBLIC void clock_handler(int irq)
{
	ticks++;
	p_proc_ready->ticks--;

	if (k_reenter != 0) {
		return;
	}

	if (p_proc_ready->ticks > 0) {
		return;
	}

	schedule();

}

/*======================================================================*
                              milli_delay
 *======================================================================*/
PUBLIC void milli_delay(int milli_sec)
{
        int t = get_ticks();

        while(((get_ticks() - t) * 1000 / HZ) < milli_sec) {}
}

/*======================================================================*
                           init_clock
 *======================================================================*/
PUBLIC void init_clock()
{
        /* 初始化 8253 PIT */
        out_byte(TIMER_MODE, RATE_GENERATOR);
        out_byte(TIMER0, (u8) (TIMER_FREQ/HZ) );
        out_byte(TIMER0, (u8) ((TIMER_FREQ/HZ) >> 8));

        put_irq_handler(CLOCK_IRQ, clock_handler);    /* 设定时钟中断处理程序 */
        enable_irq(CLOCK_IRQ);                        /* 让8259A可以接收时钟中断 */
}
/*======================================================================*
                           dummy_handler
 *======================================================================*/
PUBLIC void dummy_handler(int irq)
{
	printf("$");
	return;
}


void clear_old_pointer()
{
	vesa_draw_point(old_x, old_y, 0);
	vesa_draw_point(old_x+1, old_y, 0);
	vesa_draw_point(old_x+2, old_y, 0);

	vesa_draw_point(old_x, old_y+1, 0);
	vesa_draw_point(old_x+1, old_y+1, 0);
			
	vesa_draw_point(old_x, old_y+2, 0);
	vesa_draw_point(old_x+2, old_y+2, 0);

	vesa_draw_point(old_x+3, old_y+3, 0);

	vesa_draw_point(old_x+4, old_y+4, 0);

}

/*======================================================================*
                           mouse_handler
 *======================================================================*/
PUBLIC void mouse_parser(char ch)
{
	int new_x, new_y;

	switch(++mouse_count)
	{
		case 1:		
			x_sign = 0;
			y_sign = 0;
			TempMouseMsg.LeftButtonDown = ch & 0x1;
			TempMouseMsg.RightButtonDown = ch & 0x2;
			if (ch & 0x1) mouse_color = 4;
			if (ch & 0x2) mouse_color = 2;			
			x_sign = ch & 0x10 ? 0xffffff00 : 0 ;	  		y_sign = ch & 0x20 ? 0xffffff00 : 0 ;
			break;
		case 2:
			old_x = mouse_x;
			new_x = mouse_x + ( x_sign | ch);
			if (new_x < 319    &&  new_x > 0) mouse_x = new_x;
			TempMouseMsg.MouseX = mouse_x;
			break;
		case 3:	
			old_y = mouse_y;
			new_y = mouse_y - (y_sign | ch);
			if (new_y < 199    &&  new_y > 0) mouse_y = new_y;
			TempMouseMsg.MouseY = mouse_y;
			TempMouseMsg.BelongsTo = -1;
			mouse_count = 0;
			clear_old_pointer();
			PutMessage(&SysMessages, TempMouseMsg);
			break;
	}
	if (mouse_x> 319 || mouse_x <0 || mouse_y>199 || mouse_y <0)
	{
		clear_old_pointer();
		mouse_x = 100;
		mouse_y = 100;
	}
}

void repaint_mouse()
{
	vesa_draw_point(mouse_x, mouse_y, mouse_color);
	vesa_draw_point(mouse_x+1, mouse_y, mouse_color);
	vesa_draw_point(mouse_x+2, mouse_y, mouse_color);

	vesa_draw_point(mouse_x, mouse_y+1, mouse_color);
	vesa_draw_point(mouse_x+1, mouse_y+1, mouse_color);
			
	vesa_draw_point(mouse_x, mouse_y+2, mouse_color);
	vesa_draw_point(mouse_x+2, mouse_y+2, mouse_color);

	vesa_draw_point(mouse_x+3, mouse_y+3, mouse_color);

	vesa_draw_point(mouse_x+4, mouse_y+4, mouse_color);
}

PUBLIC void mouse_handler(int irq)
{
	//disp_str("Mouse!");
	int i, j;
	char ch = in_byte(0x60);
	mouse_parser(ch);
	unsigned short color = vesa_compond_rgb( 63 , 63 , 63 ) ;
	unsigned short color_2 = vesa_compond_rgb(0,0,0);
	vesa_draw_point(200,200,color);

	clear_old_pointer();
	repaint_mouse();
	return;	
}

/*======================================================================*
                           init_mouse
 *======================================================================*/
PUBLIC void init_mouse()
{
	mouse_x = 160;
	mouse_y = 100;
	mouse_color = 2;
	mouse_count = 2;

	disp_str("Mouse init");

	out_byte(0x64, 0xa8);
	out_byte(0x64, 0xd4);
	out_byte(0x60, 0xf4);
	out_byte(0x64, 0x60);
	out_byte(0x60, 0x47);

	put_irq_handler(MOUSE_IRQ, mouse_handler);
	enable_irq(MOUSE_IRQ);

	enable_irq(CASCADE_IRQ);
}
